/*
 * @Copyright: Copyright (c) 2030 吴周海
 * @Author: wzh200x@126.com
 * @Date: 2025-10-11 11:53:58
 * @LastEditors: wzh200x@126.com
 * @LastEditTime: 2025-10-11 14:12:43
 * @FilePath: \gogamewebserver\goGameWebServer\internal\manager\cacheManager.go
 * @Description: 文件功能描述
 */
package cachemanager

import (
	"context"
	"fmt"
	"goGameWebServer/internal/common/config"
	"goGameWebServer/internal/common/redis"
	"sync"
	"time"
)

type CacheManager struct {
	redisHelper *redis.RedisHelper
}

func (cache *CacheManager) Init(ctx context.Context, options config.ServerOptions) {
	cache.redisHelper = redis.NewRedisHelper(&options.RedisOptions)
}

func (cache *CacheManager) Put(key string, value interface{}, expire int) error {
	return cache.redisHelper.Put(key, value, expire)
}
func (cache *CacheManager) Get(key string) (string, error) {
	return cache.redisHelper.Get(key)
}

func (cache *CacheManager) Del(key string) error {
	return cache.redisHelper.Del(key)
}
func (cache *CacheManager) Exists(key string) bool {
	return cache.redisHelper.Exists(key)
}

// StoreListPush 向列表推入元素，支持最大长度限制和TTL设置
func (cache *CacheManager) StoreListPush(key string, value string, maxLength int, ttl int) (int64, error) {
	// 生成应用缓存键（这里简化处理，实际可能需要根据项目需求调整）
	cacheKey := cache.generateAppCacheKey(key)

	// 检查是否超过最大长度
	if maxLength > 0 {
		currentLength, err := cache.redisHelper.LLen(cacheKey)
		if err != nil {
			// 如果获取长度失败，记录错误但继续执行
			// 这里可以添加日志记录
		} else if currentLength >= int64(maxLength) {
			// 删除最旧的元素（从左侧弹出）
			_, err := cache.redisHelper.LPop(cacheKey)
			if err != nil {
				// 如果弹出失败，记录错误但继续执行
				// 这里可以添加日志记录
			}
		}
	}

	// 设置过期时间（如果指定了TTL）
	if ttl > 0 {
		err := cache.redisHelper.Expire(cacheKey, time.Duration(ttl)*time.Second)
		if err != nil {
			// 如果设置过期时间失败，记录错误但继续执行
			// 这里可以添加日志记录
		}
	}

	// 向列表右侧推入元素
	return cache.redisHelper.RPush(cacheKey, value)
}

// StoreListGet 获取列表中的所有元素
func (cache *CacheManager) StoreListGet(key string) ([]string, error) {
	// 生成应用缓存键
	cacheKey := cache.generateAppCacheKey(key)

	// 检查键是否存在
	if !cache.redisHelper.Exists(cacheKey) {
		// 如果键不存在，返回空数组
		return []string{}, nil
	}

	// 获取列表中的所有元素（从索引0到-1，即全部元素）
	return cache.redisHelper.LRange(cacheKey, 0, -1)
}

// StoreListDel 从列表中删除指定值的所有元素
func (cache *CacheManager) StoreListDel(key string, value string) (int64, error) {
	// 生成应用缓存键
	cacheKey := cache.generateAppCacheKey(key)

	// 检查键是否存在
	if !cache.redisHelper.Exists(cacheKey) {
		// 如果键不存在，返回0（表示删除了0个元素）
		return 0, nil
	}

	// 从列表中删除所有值为value的元素（count=0表示删除所有匹配的元素）
	return cache.redisHelper.LRem(cacheKey, 0, value)
}

// generateAppCacheKey 生成应用缓存键
// 这里提供一个简单的实现，实际项目中可能需要根据具体需求调整
func (cache *CacheManager) generateAppCacheKey(key string) string {
	// 可以添加应用前缀、环境前缀等
	return fmt.Sprintf("app:%s", key)
}

// LLen 获取列表长度
func (cache *CacheManager) LLen(key string) (int64, error) {
	return cache.redisHelper.LLen(key)
}

// LPop 从列表左侧弹出元素
func (cache *CacheManager) LPop(key string) (string, error) {
	return cache.redisHelper.LPop(key)
}

// RPush 向列表右侧推入元素
func (cache *CacheManager) RPush(key string, values ...interface{}) (int64, error) {
	return cache.redisHelper.RPush(key, values...)
}

// Expire 设置键的过期时间
func (cache *CacheManager) Expire(key string, ttl int) error {
	return cache.redisHelper.Expire(key, time.Duration(ttl)*time.Second)
}

// LRange 获取列表指定范围的元素
func (cache *CacheManager) LRange(key string, start, stop int64) ([]string, error) {
	return cache.redisHelper.LRange(key, start, stop)
}

// LRem 从列表中删除指定值的元素
func (cache *CacheManager) LRem(key string, count int64, value interface{}) (int64, error) {
	return cache.redisHelper.LRem(key, count, value)
}

func NewCacheManager() *CacheManager {
	return &CacheManager{
		redisHelper: nil,
	}
}

var cacheManager *CacheManager
var onceCacheManager sync.Once

func ManagerCache() *CacheManager {
	onceCacheManager.Do(func() {
		cacheManager = NewCacheManager()
	})
	return cacheManager
}
